package br.unicamp.ic.sgct.client.apresentacao.views;

import br.unicamp.ic.sgct.client.apresentacao.MyConstants;
import br.unicamp.ic.sgct.client.apresentacao.widgets.LabelCampoForm;
import br.unicamp.ic.sgct.client.dominio.to.AreaTO;
import br.unicamp.ic.sgct.client.dominio.to.AvaliadorTO;
import br.unicamp.ic.sgct.client.dominio.to.ChairTO;
import br.unicamp.ic.sgct.client.dominio.to.ParticipanteTO;
import br.unicamp.ic.sgct.client.dominio.to.PessoaTO;
import br.unicamp.ic.sgct.client.dominio.to.PreletorTO;
import br.unicamp.ic.sgct.client.dominio.to.UsuarioTO;
import br.unicamp.ic.sgct.client.dominio.to.VisitanteTO;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DatePicker;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.gwtiger.client.widget.field.DateFieldWidget;
import org.gwtiger.client.widget.field.MaskTextFieldWidget;
import org.gwtiger.client.widget.field.PasswordFieldWidget;
import org.gwtiger.client.widget.field.TextFieldWidget;

public class ViewInscricaoUsuarioConferencia extends Composite {
	
	private static MyConstants obterMyConstants()
	{
		return (MyConstants) GWT.create(MyConstants.class); 
	}

    private VerticalPanel panelInscricaoUsuarioConferencia = new VerticalPanel();
    private HorizontalPanel panelADDH = new HorizontalPanel();
    private HTML strTabTitle = null;
    private int index = 0;
    //dados usuario
    private TextFieldWidget txtbEmail = null;
    private PasswordFieldWidget txtbSenha = null;
    private PasswordFieldWidget txtbConfirmacao = null;
    //dados pessoais
    private TextFieldWidget txtbNome = null;
    private TextFieldWidget txtbSobreNome = null;
    private MaskTextFieldWidget txtbFone = null;
    private MaskTextFieldWidget txtbCelular = null;
    private ListBox lbPerfil = null;
    private ListBox lbArea = null;
    //
    private String strDataPagto;
    private Date data;
    //
    private DateFieldWidget dtField;
    //
    private static final String MSG_REQUIRED_ERR = obterMyConstants().mensagemREQUIREDERR();
    private static final String MSG_PASSWD_ERR = obterMyConstants().mensagemPASSWDERR();
    private static final String MSG_PASSWD_SIZE_ERR = obterMyConstants().mensagemPASSWDSIZEERR();
    private static final String MSG_NOME_ERR = obterMyConstants().mensagemNOMEERR();
    private static final String MSG_EMAIL_ERR = obterMyConstants().mensagemEMAILERR();
    private static final String MSG_SOBRENOME_ERR = obterMyConstants().mensagemSOBRENOMEERR();
    private static final String MSG_CELULAR_ERR = obterMyConstants().mensagemCELULARERR();
    private static final String MSG_FONE_ERR = obterMyConstants().mensagemFONEERR();
    private static final String MSG_DATA_ERR = obterMyConstants().mensagemDATAERR();

    public ViewInscricaoUsuarioConferencia(String title, int index) {

        this.index = index;
        this.strTabTitle = new HTML(title);
        initPanel();
        panelInscricaoUsuarioConferencia.add(panelADDH);
        initWidget(panelInscricaoUsuarioConferencia);
    }

    public ViewInscricaoUsuarioConferencia addH(Widget w) {
        panelADDH.add(w);
        return this;
    }

    public void clear() {
        txtbConfirmacao.clear();
        txtbSenha.clear();
        txtbEmail.clear();
        txtbNome.clear();
        txtbSobreNome.clear();
        txtbFone.clear();
        txtbCelular.clear();
        dtField.clear();

    }

    /**
     * Passa como parametro um dos usuário desta pessoa
     * se pessoa não tiver nenhum usuário passa um usuário
     * novo (com atributo pessoa inicializada) e todos os campos deverão ser editáveis
     * montarInscricaoUI
     */
    private void initPanel() {
        FlexTable tblUsuario = new FlexTable();
        txtbEmail = new TextFieldWidget(obterMyConstants().email());
        txtbEmail.setRequired(true);
        tblUsuario.setWidget(0, 0, txtbEmail);
        txtbSenha = new PasswordFieldWidget(obterMyConstants().senha());
        txtbSenha.setRequired(true);
        tblUsuario.setWidget(1, 0, txtbSenha);
        txtbConfirmacao = new PasswordFieldWidget(obterMyConstants().confirmacoes());
        txtbConfirmacao.setRequired(true);
        tblUsuario.setWidget(1, 1, txtbConfirmacao);
        txtbNome = new TextFieldWidget(obterMyConstants().nome());
        txtbNome.setRequired(true);
        tblUsuario.setWidget(2, 0, txtbNome);
        txtbSobreNome = new TextFieldWidget(obterMyConstants().sobrenome());
        txtbSobreNome.setRequired(true);
        tblUsuario.setWidget(2, 1, txtbSobreNome);
        txtbFone = new MaskTextFieldWidget(obterMyConstants().fone(), "(###) ####-####");
        tblUsuario.setWidget(3, 0, txtbFone);
        txtbCelular = new MaskTextFieldWidget(obterMyConstants().celular(), "(###) ####-####");
        tblUsuario.setWidget(3, 1, txtbCelular);
        dtField = new DateFieldWidget(obterMyConstants().dataEfetivacaoPagamento());
        dtField.setRequired(true);
        dtField.setDateFormat(ViewUtil.timeFormat);
        dtField.setMask("##/##/####");
        dtField.setEnabled(false);
        DatePicker dtPicker = new DatePicker();
        dtPicker.setValue(new Date(), true);
        DateBox dtBox = new DateBox(dtPicker, null, new DateBox.DefaultFormat(ViewUtil._dtTimeFormat));
        dtBox.addValueChangeHandler(new ValueChangeHandler<Date>() {

            @Override
            public void onValueChange(ValueChangeEvent<Date> event) {
                data = event.getValue();
                strDataPagto = ViewUtil._dtTimeFormat.format(data);
                dtField.setText(strDataPagto);
            }
        });
        tblUsuario.setWidget(4, 0, dtField);
        tblUsuario.setWidget(4, 1, dtBox);
        //
        HorizontalPanel panellbPerfil = new HorizontalPanel();
        HorizontalPanel panellbArea = new HorizontalPanel();
        lbPerfil = new ListBox();
        lbPerfil.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
            }
        });
        LabelCampoForm labelArea = new LabelCampoForm(obterMyConstants().area());
        lbArea = new ListBox(true);
        //lbArea.setVisible(false);
        //labelArea.setVisible(false);
        panellbPerfil.add(new LabelCampoForm(obterMyConstants().perfil()));
        panellbPerfil.add(lbPerfil);
        panellbArea.add(labelArea);
        panellbArea.add(lbArea);
        tblUsuario.setWidget(5, 0, panellbPerfil);
        tblUsuario.setWidget(5, 1, panellbArea);
        tblUsuario.setCellSpacing(2);
        tblUsuario.setCellPadding(2);
        panelInscricaoUsuarioConferencia.add(tblUsuario);
        //panelInscricaoUsuarioConferencia.add(initPanelBtn());
    }

    public void montar(UsuarioTO usuario, List<UsuarioTO> listUsuario, List<AreaTO> areasConferencia) {
        lbPerfil.clear();
        lbArea.clear();
        txtbConfirmacao.clear();
        txtbSenha.clear();
        txtbEmail.clear();
        txtbNome.clear();
        txtbSobreNome.clear();
        txtbFone.clear();
        txtbCelular.clear();
        dtField.clear();
        if (usuario != null) {
            txtbEmail.setText(usuario.getEmail());
            txtbSenha.setText(usuario.getSenha());
            txtbNome.setText(usuario.getPessoa().getNome());
            txtbSobreNome.setText(usuario.getPessoa().getSobreNome());
            txtbFone.setText(usuario.getPessoa().getFoneResidencial());
            txtbCelular.setText(usuario.getPessoa().getCelular());
            if (usuario.getDataEfetivacaoPagto() != null) {
                dtField.setText(ViewUtil._dtTimeFormat.format(usuario.getDataEfetivacaoPagto()));
            }
            if (usuario.getPessoa().getIdPessoa() != null) {
                txtbNome.setEnabled(false);
                txtbSobreNome.setEnabled(false);
            }
        }
        montarPerfis(listUsuario);
        montarAreas(areasConferencia);

    }

    private void montarAreas(List<AreaTO> areasConferencia) {

        if (areasConferencia.size() > 5) {
            lbArea.setVisibleItemCount(5);
        } else {
            lbArea.setVisibleItemCount(areasConferencia.size());
        }
        for (AreaTO area : areasConferencia) {
            lbArea.addItem(area.getNome(), String.valueOf(area.getId()));
        }

    }

    public boolean montarPerfis(List<UsuarioTO> listUsuario) {
        boolean retorno = false;
        if (addPerfil(listUsuario, ParticipanteTO.class)) {
            lbPerfil.addItem(obterMyConstants().participante());
            retorno = true;
        }
        if (addPerfil(listUsuario, AvaliadorTO.class)) {
            lbPerfil.addItem(obterMyConstants().avaliador());
            retorno = true;
        }
        if (addPerfil(listUsuario, ChairTO.class)) {
            lbPerfil.addItem(obterMyConstants().Chair());
            retorno = true;
        }
        if (addPerfil(listUsuario, PreletorTO.class)) {
            lbPerfil.addItem(obterMyConstants().Preletor());
            retorno = true;
        }
        if (addPerfil(listUsuario, VisitanteTO.class)) {
            lbPerfil.addItem(obterMyConstants().Visitante());
            retorno = true;
        }
        return retorno;
    }

    private boolean addPerfil(List<UsuarioTO> listUsuario, Class clazz) {
        boolean retorno = true;
        if (listUsuario != null) {
            for (int i = 0; i < listUsuario.size(); i++) {
                UsuarioTO usuarioTO = listUsuario.get(i);
                if (usuarioTO.getClass().equals(clazz)) {
                    retorno = false;
                    break;
                }
            }
        }
        return retorno;
    }

    /**
     *
     * @return uma lista de mgs dos erros
     */
    public List<String> validate() {
        List<String> mgs = new ArrayList<String>();
        if (!(txtbSenha.validate()
                && txtbConfirmacao.validate()
                && txtbEmail.validate()
                && txtbNome.validate()
                && txtbSobreNome.validate()
                && dtField.validate()
                && (strDataPagto != null ? true : false))) {
            mgs.add(MSG_REQUIRED_ERR);
        }
        if (txtbSenha.getText() != null && !txtbSenha.getText().equals(txtbConfirmacao.getText())) {
            mgs.add(MSG_PASSWD_ERR);

        } //maiuscula, campo obrigatorio
        if (txtbSenha.getText() != null && txtbSenha.getText().length() < 2 || txtbSenha.getText().length() > 8) {
            mgs.add(MSG_PASSWD_SIZE_ERR);
        } // Nome: tamanho minimo igual a 2 caracteres e tamanho maximo igual a
        // 15 caracteres, apenas letras
        if (txtbNome.getText() != null && txtbNome.getText().length() < 2 || txtbNome.getText().length() > 19) {
            mgs.add(MSG_NOME_ERR);
        } // Sobrenome: tamanho maximo igual a 15 caracteres, apenas letras,
        // campo obrigatorio
        // TODO Falha aqui, esquece de tratar A,z
        if (txtbSobreNome.getText() != null && txtbSobreNome.getText().length() > 25) {
            mgs.add(MSG_SOBRENOME_ERR);
        } // Email: tamanho maximo igual a 30 caracteres, apenas emails validos;
        // TODO Falha aqui, so procura pela @
        if (txtbEmail.getText() != null && txtbEmail.getText().length() > 30 || !txtbEmail.getText().contains("@")) {
            //|| (!(Pattern.compile("(\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,6})").
            mgs.add(MSG_EMAIL_ERR);
        } // Fone residencial: tamanho maximo igual a 18 caracteres, sem letras
        // TODO Falha aqui, nao aceita caracteres especiais
        if (txtbFone.getText() != null && txtbFone.getText().length() > 18) {
            mgs.add(MSG_FONE_ERR);
        } // Fone celular: tamanho maximo igual a 18 caracteres, sem letras
        if (txtbCelular.getText() != null && txtbCelular.getText().length() >= 18) {
            mgs.add(MSG_CELULAR_ERR);
        }
        Date dataAtual = new Date(System.currentTimeMillis());
        Date dataPgto = data;
        if (dataPgto == null) {
            mgs.add(MSG_REQUIRED_ERR);
        } else {
            if (dataPgto.after(dataAtual)) {
                mgs.add(MSG_DATA_ERR);
            }

        }
        return mgs;
    }

    public UsuarioTO criar(PessoaTO pessoa, String username) {
        UsuarioTO usuario = obterUsuario();
        // tem que definir o tipo do usuário (Participante, Avaliador e etc)
        usuario.setEmail(txtbEmail.getText());
        usuario.setSenha(txtbSenha.getText());
        usuario.setInscricaoAtiva("S");

        if (dtField.getText() != null && !"".equals(dtField.getText())) {
            usuario.setDataEfetivacaoPagto(ViewUtil._dtTimeFormat.parse(strDataPagto));
        }
        if (pessoa == null) {
            pessoa = new PessoaTO();
            pessoa.setNome(txtbNome.getText());
            pessoa.setSobreNome(txtbSobreNome.getText());
        }
        pessoa.setFoneResidencial(txtbFone.getText());
        pessoa.setCelular(txtbCelular.getText());
        usuario.setPessoa(pessoa);
        usuario.setUsername(username);
        return usuario;
    }

    private List<AreaTO> areasSelecionadas() {
        List<AreaTO> areas = new ArrayList<AreaTO>();
        int size = lbArea.getItemCount();
        for (int i = 0; i < size; i++) {
            if (lbArea.isItemSelected(i)) {
                String idArea = lbArea.getValue(i);
                areas.add(new AreaTO(Long.parseLong(idArea)));
            }
        }
        return areas;

    }

    private UsuarioTO obterUsuario() {
        String nomePerfil = lbPerfil.getItemText(lbPerfil.getSelectedIndex());
        UsuarioTO usuario = null;
        if (nomePerfil.equals(obterMyConstants().participante())) {
            ParticipanteTO partici = new ParticipanteTO();
            partici.setAreasTO(areasSelecionadas());
            usuario = partici;
        } else {
            if (nomePerfil.equals(obterMyConstants().avaliador())) {
                AvaliadorTO ava = new AvaliadorTO();
                ava.setAreasTO(areasSelecionadas());
                usuario = ava;
            } else {
                if (nomePerfil.equals(obterMyConstants().Chair())) {
                    usuario = new ChairTO();
                } else {
                    if (nomePerfil.equals(obterMyConstants().Visitante())) {
                        usuario = new VisitanteTO();
                    } else {
                        if (nomePerfil.equals(obterMyConstants().Preletor())) {
                            usuario = new PreletorTO();
                        }
                    }
                }
            }
        }
        return usuario;
    }

    /**
     * @return the strTabTitle
     */
    public HTML getStrTabTitle() {
        return strTabTitle;
    }
}
